/**
 * 工具函数入口文件
 */

export * from './date.js'
export * from './string.js'
export * from './validate.js'

/**
 * 防抖函数
 * @param {Function} func 要防抖的函数
 * @param {number} delay 延迟时间（毫秒）
 * @returns {Function} 防抖后的函数
 */
export function debounce(func, delay) {
  let timeoutId
  return function (...args) {
    clearTimeout(timeoutId)
    timeoutId = setTimeout(() => func.apply(this, args), delay)
  }
}

/**
 * 节流函数
 * @param {Function} func 要节流的函数
 * @param {number} delay 延迟时间（毫秒）
 * @returns {Function} 节流后的函数
 */
export function throttle(func, delay) {
  let lastCall = 0
  return function (...args) {
    const now = Date.now()
    if (now - lastCall >= delay) {
      lastCall = now
      return func.apply(this, args)
    }
  }
}

/**
 * 深拷贝
 * @param {any} obj 要拷贝的对象
 * @returns {any} 拷贝后的对象
 */
export function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj
  if (obj instanceof Date) return new Date(obj.getTime())
  if (obj instanceof Array) return obj.map(item => deepClone(item))
  
  const cloned = {}
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      cloned[key] = deepClone(obj[key])
    }
  }
  return cloned
}

/**
 * 生成UUID
 * @returns {string} UUID字符串
 */
export function generateUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    const r = Math.random() * 16 | 0
    const v = c === 'x' ? r : (r & 0x3 | 0x8)
    return v.toString(16)
  })
}

/**
 * 获取存储数据
 * @param {string} key 存储键
 * @param {any} defaultValue 默认值
 * @returns {any} 存储的数据
 */
export function getStorage(key, defaultValue = null) {
  try {
    const value = uni.getStorageSync(key)
    return value !== '' && value !== null ? value : defaultValue
  } catch (error) {
    console.error('获取存储数据失败:', error)
    return defaultValue
  }
}

/**
 * 设置存储数据
 * @param {string} key 存储键
 * @param {any} value 存储值
 * @returns {boolean} 是否成功
 */
export function setStorage(key, value) {
  try {
    uni.setStorageSync(key, value)
    return true
  } catch (error) {
    console.error('设置存储数据失败:', error)
    return false
  }
}

/**
 * 移除存储数据
 * @param {string} key 存储键
 * @returns {boolean} 是否成功
 */
export function removeStorage(key) {
  try {
    uni.removeStorageSync(key)
    return true
  } catch (error) {
    console.error('移除存储数据失败:', error)
    return false
  }
}

/**
 * 显示提示信息
 * @param {string} title 提示内容
 * @param {string} icon 图标类型
 * @param {number} duration 显示时长
 */
export function showToast(title, icon = 'none', duration = 2000) {
  uni.showToast({
    title,
    icon,
    duration,
    mask: true
  })
}

/**
 * 显示加载中
 * @param {string} title 加载提示
 * @param {boolean} mask 是否显示遮罩
 */
export function showLoading(title = '加载中...', mask = true) {
  uni.showLoading({
    title,
    mask
  })
}

/**
 * 隐藏加载中
 */
export function hideLoading() {
  uni.hideLoading()
}

/**
 * 显示确认对话框
 * @param {string} content 对话框内容
 * @param {string} title 对话框标题
 * @returns {Promise<boolean>} 用户选择结果
 */
export function showConfirm(content, title = '提示') {
  return new Promise((resolve) => {
    uni.showModal({
      title,
      content,
      success: (res) => {
        resolve(res.confirm)
      },
      fail: () => {
        resolve(false)
      }
    })
  })
}

/**
 * 验证并修正坐标值
 * @param {number|string} latitude 纬度
 * @param {number|string} longitude 经度
 * @param {object} defaultCoords 默认坐标 {latitude, longitude}
 * @returns {object} 修正后的坐标 {latitude, longitude}
 */
export function validateCoordinates(latitude, longitude, defaultCoords = {latitude: 30.5734, longitude: 114.2734}) {
  // 转换为数字类型
  let lat = parseFloat(latitude) || defaultCoords.latitude;
  let lng = parseFloat(longitude) || defaultCoords.longitude;
  
  // 验证纬度范围：[-90, 90]
  if (lat < -90 || lat > 90 || isNaN(lat)) {
    console.warn(`无效的纬度值: ${latitude}，使用默认值: ${defaultCoords.latitude}`);
    lat = defaultCoords.latitude;
  }
  
  // 验证经度范围：[-180, 180]
  if (lng < -180 || lng > 180 || isNaN(lng)) {
    console.warn(`无效的经度值: ${longitude}，使用默认值: ${defaultCoords.longitude}`);
    lng = defaultCoords.longitude;
  }
  
  return {
    latitude: lat,
    longitude: lng
  };
}